package com.example.websocketdemo;

import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author HXB
 * @Title:
 * @Package
 * @Description:
 * @date 2020-03-2116:31
 */
//@ServerEndpoint("/websocket/{user}")
//@Component
public class websocket {

    private static final String loggerName = websocket.class.getName();
    //concurrent包的线程安全Set，用来存放每个客户端对应的MyWebSocket对象。若要实现服务端与单一客户端通信的话，可以使用Map来存放，其中Key可以为用户标识
    public static Map<String, List<Session>> electricSocketMap = new ConcurrentHashMap<String, List<Session>>();

    private static Map<String,List<String>> messageMap = new ConcurrentHashMap<>();
    /**
     * 连接建立成功调用的方法
     *
     * @param session 可选的参数。session为与某个客户端的连接会话，需要通过它来给客户端发送数据
     */
    @OnOpen
    public void onOpen(@PathParam("user") String user, Session session) {
        System.out.println("连接建立成功"+user);
        List<Session> sessions = electricSocketMap.get(user);
        if (null == sessions) {
            List<Session> sessionList = new ArrayList<>();
            sessionList.add(session);
            electricSocketMap.put(user, sessionList);
        } else {
            sessions.add(session);
        }
        if(messageMap.containsKey(user)){
            for (String m :messageMap.get(user)){
                sendMessage(m,user);
            }
            messageMap.remove(user);
        }
    }

    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose(@PathParam("user") String user, Session session) {
        System.out.println("关闭调用");
        //在这记录离线消息
        if (electricSocketMap.containsKey(user)) {
            electricSocketMap.get(user).remove(session);
        }
    }

    /**
     * 收到客户端消息后调用的方法
     *
     * @param message 客户端发送过来的消息
     * @param session 可选的参数
     */
    @OnMessage
    public void onMessage(String message, Session session) {
        System.out.println("websocket received message:" + message);
        try {
            //返回成功
            session.getBasicRemote().sendText("这是推送测试数据！您刚发送的消息是：" + message);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 发生错误时调用
     *
     * @param session
     * @param error
     */
    @OnError
    public void onError(Session session, Throwable error) {
        System.out.println("发生错误"+error.getMessage());
    }

    /**
     * 对外发送消息
     *
     * @param message
     */
    public static boolean sendMessage(String message, Session session) {
        try {
            session.getBasicRemote().sendText(message);
        } catch (IOException e) {
            System.out.println(e.getMessage());
            return false;
        }
        return true;
    }

    /**
     * 对某个机器发送消息
     *
     * @param message
     * @param user   用户编号
     * @return true, 返回发送的消息, false，返回failed字符串
     */
    public static String sendMessage(String message, String user) {
        boolean success = false;
        try {
            for (Session session : electricSocketMap.get(user)) {
                success = sendMessage(message, session);
            }
            if(success){
                return message;
            }
        }catch (Exception e){
            System.out.println(e.getMessage());
        }
        System.out.println("保存离线：ToUser:"+user+",消息："+message);
        if(messageMap.containsKey(user)){
            messageMap.get(user).add(message);
        }else {
            List<String> list = new ArrayList<>();
            list.add(message);
            messageMap.put(user,list);
        }
        return "failed";
    }


}
